package com.stone.framework.batch.tasklet;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.step.tasklet.SystemCommandTasklet;
import org.springframework.util.Assert;

/**
 * 调用方式与{@link SystemCommandTasklet}相同，解决linux下shell通配符不识别的问题
 * 
 * @author ybliu
 * @date 2020/07/27
 */
public class DefaultSystemCommandTasklet extends SystemCommandTasklet {

    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSystemCommandTasklet.class);

    private String workingDirectory;
    private String command;

    private Path tempFile;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.hasLength(this.command, "command is required");
        Assert.hasLength(this.workingDirectory, "workingDirectory is required");

        this.tempFile = this.createTempFile();
        String command = this.buildCommand();
        super.setCommand(command);

        super.afterPropertiesSet();
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        try {
            Files.deleteIfExists(this.tempFile);
        } catch (IOException e) {
            LOGGER.error("删除临时文件失败：{}", this.tempFile.toAbsolutePath().toString());
        }
        return ExitStatus.COMPLETED;
    }

    public void setWorkingDirectory(String workingDirectory) {
        this.workingDirectory = workingDirectory;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    private Path createTempFile() throws IOException {
        Path path = Files.createTempFile(Paths.get(this.workingDirectory), "temp", ".sh");
        LOGGER.info("创建临时文件：{}", path.toAbsolutePath().toString());
        List<String> lines = Arrays.asList("#!/bin/sh", this.command);
        Files.write(path, lines, StandardOpenOption.WRITE);
        return path;
    }

    private String buildCommand() {
        String command = "sh ".concat(this.tempFile.toAbsolutePath().toString());
        LOGGER.info("生成command: {}", command);
        return command;
    }

}
